import express from 'express'
import { createServer } from 'http'
import WS from 'ws'
import Cfg from '../model/config/config.js'
import OneBot, { OneBotv11WS } from './OneBotV11/index.js'
import stdin from './Bot/stdin.js'


class WebSocket {
  constructor () {
    this.count = 0
    this.port = Cfg.port
    this.path = {
      '/onebot/v11/ws': OneBotv11WS
    }
    this.server()
    this.client()
    stdin()
  }

  async server () {
    /** 保存监听器返回 */
    lain.echo = new Map()
    /** 临时文件 */
    lain.Files = new Map()
    /** 创建Express应用程序 */
    const app = express()
    /** 创建HTTP服务器 */
    this.Server = createServer(app)

    /** 设置静态文件服务 */
    app.use('/api/File', express.static(process.cwd() + '/temp/FileToUrl'))

    /** 将WebSocket服务器实例与HTTP服务器关联 */
    this.Server.on('upgrade', (request, socket, head) => {
      const pathname = request.url
      if (!this.path[pathname]) {
        logger.error(`未知连接，已拒绝连接：${request.url}`)
        return socket.destroy()
      }
      this.path[pathname].handleUpgrade(request, socket, head, (socket) => {
        this.path[pathname].emit('connection', socket, request)
      })
    })

    this.Server.listen(this.port, async () => this.log())

    /** 捕获错误 */
    this.Server.on('error', async (error) => {
      if (error.code === 'EADDRINUSE') {
        logger.error(`[Lain-plugin] 端口${this.port}已被占用请自行解除`)
      } else {
        logger.error(error)
      }
    })
  }

  /** 打印启动日志 */
  log () {
    logger.info('Lain-plugin', `HTTP服务器：${logger.blue(`http://localhost:${this.port}`)}`)
    /** 转为数组对象，循环打印 */
    Object.entries(this.path).forEach(([key, value]) => {
      logger.info('Lain-plugin', `本地 ${key.replace('/', '')} 连接地址：${logger.blue(`ws://localhost:${this.port}${key}`)}`)
    })
  }
  async client(ws){
    let data = Cfg.config['config.Config-bot'].Client
    if(!data.qq || !data.ws) return false
    try {
      ws = new WS(data.ws, { headers: { Authorization: `Bearer ${data.token}` }});
    } catch (error) {
      //logger.error(error)
    }
    ws.on('open', async () => {
      const request = { headers: {'x-self-id': data.qq } };
      new OneBot(ws, request);
    });
    
    // 关闭处理
    ws.on('close', (code, reason) => {
      this.count++
      logger.warn(`开始尝试重新连接第${this.count}`);
      setTimeout(() => { this.client();}, 5 * 1000)
    });
    // 错误处理
    ws.on('error', (error) => {
      logger.info('链接失败', error);
    });
  }
}

export default new WebSocket()
